﻿using System;
using System.Collections.Generic;
using DependencyAnalysis.DataModel;

namespace DependencyAnalysis.Serialization
{
    public class DuplicationReport : IReport
    {
        public Setup Setup { get; set; }

        public IReportObject FetchReport<T>() where T : IReportObject, new()
        {
            if (Setup == null) throw new InvalidOperationException();
            dynamic report = new T();
            report.Name = "Code Duplication";
            report.Type = "Report";

            var duplicates = Principles.DontRepeatYourself(Setup.Model, 40);

            var duplicationReportItems = ConvertToExpandoObjects<T>(duplicates);
            report.Duplicates = duplicationReportItems;
            return report;
        }

        private IList<T> ConvertToExpandoObjects<T>(IEnumerable<CodeDuplicate> duplicates) where T : IReportObject, new()
        {
            var duplicationReportItems = new List<T>();
            foreach (var duplicate in duplicates)
            {
                dynamic reportItem = new T {TypeName = "Duplicate"};
                reportItem.Length = duplicate.NumberOfInstructions;
                var duplicateMembers = new List<T>();
                for (int i = 0; i < duplicate.Members.Length; i++)
                {
                    var member = duplicate.Members[i];
                    dynamic duplicateMember = new T {TypeName = "Member"};
                    duplicateMember.Name = member.FullName;
                    duplicateMember.StartIndex = duplicate.StartIndices[i];
                    duplicateMember.NumberOfInstructions = Setup.Metrics.NumberOfInstructions(member);
                    duplicateMembers.Add(duplicateMember);
                }
                reportItem.Members = duplicateMembers;
                duplicationReportItems.Add(reportItem);
            }
            return duplicationReportItems;
        }
    }
}
